---
title: Hydration
description: Hydration is the process of making the initial pre-rendered html of a website interactive.
---

<Info>
This page is only relevant when using **static** or **server** mode.
</Info>

---

While pre-rendering your components on the server (or at built time with 'static' mode) allows for a fast "first contentful paint"
(when useful content is first displayed to the user), the site is **not interactive** (e.g. responding to button clicks) until the
client-side rendering is started and event handlers have been attached.

In static and server mode your apps lifecycle always **starts on the server**, which builds your components once and render
them to html. Then when the browser has loaded your site along with additional files like `.js` or images, your app is executed
**again on the client** to continue rendering on the client. This "picking up rendering on the client" is called **Hydration**.

> The terms "Pre-Rendering" and "Server-Side-Rendering" can be use pretty much interchangeably. "Server" in this context just refers to whatever
> computer performs the initial rendering away from the user's browser. This may be an actual webserver running in some datacenter, but
> when using "static" mode this can also be just your computer or e.g. the machine running your ci pipeline.

## Hydration Setup

For hydration to happen seamlessly the initial client-side render has to match the previously pre-rendered html from the server exactly.
This is achieved by re-executing the same components that have previously pre-rendered the html on the server also
on the client as soon as the browser loads the page.

With Jaspr you can handle hydration in two ways:

- **manually** by writing both server and client entrypoints separately, or
- **automatically** by using the `@client` annotation.

<Info>
    It is generally recommended to use automatic hydration.
</Info>

---

### Automatic Hydration (Recommended)

For automatic hydration simply use the `@client` annotation on any component.

A component annotated with `@client` will be automatically hydrated on the client after it has been pre-rendered. In principle,
this is like 'resuming' the rendering for a component on the client and picking up where the server-side rendering has left off.

Read more about `@client` components and how to best use them [here](/api/utils/at_client).

---

### Manual Hydration

With manual hydration, you need to create a separate client entrypoint for your app inside the `web/` directory:

```dart title="web/main.dart"
// Client-specific import
import 'package:jaspr/browser.dart';

// Our main component
import 'lib/app.dart';

void main() {
  // Attaches the app component to the <body> tag
  // and hydrates the component / makes it interactive.
  runApp(App(), attachTo: 'body');
}
```

This entrypoint, as any `.dart` file, will then be compiled to javascript as `<filename>.dart.js`.
To load this compiled javascript file on the client, include it as a `<source>` element in your server-rendered html:

```dart title="lib/main.dart"
// Server-specific import
import 'package:jaspr/server.dart';

// Our main component
import 'app.dart';

import 'jaspr_options.dart';

void main() {
    Jaspr.initializeApp(options: defaultJasprOptions);

    runApp(Document(
      head: [
        // Links to the compiled `web/main.dart` file.
        script(src: 'main.dart.js', []),
      ],
      // Pre-renders the [App] component inside the <body> tag
      body: App(),
    ));
}
```

The above setup mounts the `App()` component directly inside the `<body>` element. However, when you are building a more
content-heavy or mostly static website (static meaning without much user interaction)
you probably don't need to ship your whole app structure to the client, but rather want only certain parts of your
app to be interactive.

You can choose which part(s) of your app you want to hydrate by mounting only that part in your client entrypoint.
Additionally on the client, you can call `runApp()` multiple times to mount different parts of your app separately:

Assuming you have a page layout like this:

```html
<body>
<header>...</header>
<main>
    <div id="content">...</div>
    <div id="sidebar">...</div>
</main>
<footer>...</footer>
</body>
```

Your client entrypoint could be:

```dart title="web/main.dart"
void main() {
  runApp(Header(), attachTo: 'header');
  runApp(Sidebar(), attachTo: '#sidebar');
  runApp(Content(), attachTo: '#content');
}
```


This will run three apps simultaneously, attached to the specified root elements using css selectors.

The advantage of this approach is that you can leave other parts of your app, e.g. a static footer,
out of the bundled javascript and thereby reducing loading and startup time.

**Be aware** that on the server, you must still construct the complete app layout and and render the
targeted island components manually at the right location.

